package com.simen.invoker;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by zhangming on 16/8/2.
 */
public class InvokeHelper {
    /**
     * 判断classType是否是一个基本数据类型(9个预定义的Class对象来表示的八种原始类型(布尔，字节，字符，短整型，长整型，浮点和双精度)和无效(void))
     */
    public static boolean isBasicType(Class<?> classType) {
        return classType.isPrimitive();
    }

    /**
     * 判断两个类是否在同一个package下
     */
    public static boolean inSamePackage(Class<?> a, Class<?> b) {
        if (a.getClassLoader() != b.getClassLoader()) {
            return false;
        }
        String packageName1 = getPackageName(a);
        String packageName2 = getPackageName(b);
        if (packageName1 == null) {
            return packageName2 == null;
        } else if (packageName2 == null) {
            return false;
        } else {
            return packageName1.equals(packageName2);
        }
    }

    /**
     * Returns the package name of this class. This returns null for classes in
     * the default package.
     */
    public static String getPackageName(Class<?> a) {
        String name = a.getName();
        int last = name.lastIndexOf('.');
        return last == -1 ? null : name.substring(0, last);
    }

    public static Set<Method> getAnnotatedMethods(Class<?> classType, Class<? extends Annotation> annotateType) {
        Set<Method> methods = new HashSet<Method>();
        for (Method method : classType.getDeclaredMethods()) {
            // The compiler sometimes creates synthetic bridge methods as part of the
            // type erasure process. As of JDK8 these methods now include the same
            // annotations as the original declarations. They should be ignored for
            // subscribe/produce.
            if (method.isBridge()) {
                continue;
            }
            if (method.isAnnotationPresent(annotateType)) {
                methods.add(method);
            }
        }
        return methods;
    }

    public static boolean isMethodPublic(Method method) {
        if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
            return false;
        }
        return true;
    }

    public static Class<?> getMethodReturn(Method method) {
        return method.getReturnType();
    }

}
